package p3_student;


import java.awt.image.BufferedImage;

import photo.Photograph;
import photo.Pixel;

/**
 * This class will be written by the Student.  It provides various
 * static methods that take a photograph and produce a copy of it with
 * various modifications.
 * 
 * See the project description for details of method implementations.
 * 
 * @author Alishba Khawaja(112666668)
 * 
 * TA : Jason Filippou
 * 
 *
 */
public class PhotoTools {

	/**
	 * This method makes a copy of the photo passed and then returns it
	 * @param photo is a picture passed by the user
	 * @return it returns a copy of the passed photo
	 * 
	 * 
	 */

	public static Photograph copy(Photograph photo) {

		Photograph graphicPhoto = new Photograph(photo.getWidth(),
				photo.getHeight());
		
		for(int col = 0; col < photo.getWidth(); col++){
			for(int row = 0; row < photo.getHeight(); row++){
				Pixel pix = photo.getPixel(col,row);
				graphicPhoto.setPixel(col, row, pix);
			}
		}
		return graphicPhoto;
	}

	/**
	 * This method takes the photo passed, makes a copy of that photo and turns
	 * the copied photo into shades of black and white and then returns this 
	 * edited photo
	 * @param photo is a picture that is passed by the user
	 * @return it returns a black and white picture
	 * 
	 * 
	 */
	
	public static Photograph makeBlackAndWhite(Photograph photo) {
		
		Photograph newPhoto = copy(photo);// copying the photo passed

		for(int col = 0; col < photo.getWidth(); col++){
			for(int row = 0; row < photo.getHeight(); row++){
				Pixel pix = newPhoto.getPixel(col, row);
				int x = pix.getGreen();// x saves the level of green
				int y = pix.getBlue();// y saves the level of blue
				int z = pix.getRed();// z saves the level of red
				int average = (x+y+z)/3;// takes the average of 3 colors
				Pixel pixel = new Pixel(average, average, average);
				newPhoto.setPixel(col, row, pixel);
			}
		}
		return newPhoto;
	}

	/**
	 * This method takes the photo passed, makes a copy of that photo
	 * and turns that copied photo into one in which the first
	 * 10 columns of pixels are of the original color of the copied photo and 
	 * the next 10 columns of copied photo have their pixels set as black,
	 * giving a black stripe. This continues until the method has gone 
	 * through all the pixels of the columns
	 * @param photo is a picture passed by the user
	 * @return it returns a picture with black stripes
	 * 
	 */
	
	public static Photograph striped(Photograph photo) {
		Photograph striped = copy(photo);//copying the photo passed
		
		for(int col=10; col < striped.getWidth(); col++){//start black column 
			                                             //after 10 pixels of 
			                                             //original photo
			if(col>10 && col % 10 == 0){
				col = col + 10;//to leave next 10 pixel column of original photo
			}
			for(int row = 0  ; row < striped.getHeight(); row++){
				Pixel pixel = new Pixel(0,0,0);
				striped.setPixel(col, row, pixel);
			}
		}
		return striped;
	}

	/**
	 * This method takes the photo passed, makes a copy of that picture and
	 * changes the colors of its pixels to either red or green or blue and then 
	 * returns this edited photo
	 * @param photo is a picture passed by the user
	 * @return it returns a picture that is colored all red or all green or all
	 * blue
	 * 
	 * 
	 */

	public static Photograph isolateColor(Photograph photo, int type) {
		
		Photograph isolateColorPhoto = copy(photo);//copying the photo passed
		
		if(type == 0){// red only
			for(int col = 0; col < photo.getWidth(); col++){
				for(int row = 0; row < photo.getHeight(); row++){
					Pixel pix = photo.getPixel(col, row);
					int red = pix.getRed();
					Pixel anotherPix = new Pixel(red, 0, 0);
					isolateColorPhoto.setPixel(col, row, anotherPix);
				}
			}

		}else if(type == 1){// green only
			for(int col = 0; col < photo.getWidth(); col++){
				for(int row = 0; row < photo.getHeight(); row++){
					Pixel pix = photo.getPixel(col, row);
					int green = pix.getGreen();
					Pixel anotherPix = new Pixel(0, green, 0);
					isolateColorPhoto.setPixel(col, row, anotherPix);
				}
			}

		}else if(type == 2){// blue only
			for(int col = 0; col < photo.getWidth(); col++){
				for(int row = 0; row < photo.getHeight(); row++){
					Pixel pix = photo.getPixel(col, row);
					int blue = pix.getBlue();
					Pixel anotherPix = new Pixel(0, 0, blue);
					isolateColorPhoto.setPixel(col, row, anotherPix);
				}
			}
		}
		return isolateColorPhoto;
	}

	/**
	 * This method makes a new photo which is stretched to be twice as wide or
	 * twice as long depending on the user's selection and then returns that 
	 * edited photo
	 * @param is a picture passed by the user
	 * @return it returns a picture that either is stretched vertically or 
	 * horizontally
	 * 
	 * 
	 */

	public static Photograph stretched(Photograph photo, int type) {

		Photograph horizontalStretched = new Photograph(2*photo.getWidth(),
				photo.getHeight());
		
		if(type == 0){//horizontal stretch
			
			int stretchedCol = 0;//column for the stretched photo
			
			for(int row = 0; row < photo.getHeight(); row++){
				for(int col = 0; col < photo.getWidth(); col++ ){
					Pixel pix = photo.getPixel(col, row);
					horizontalStretched.setPixel(stretchedCol, row, pix);
					horizontalStretched.setPixel(stretchedCol+1, row, pix);
					stretchedCol = stretchedCol + 2;//since we want to jump
					                                //two columns
				}
				stretchedCol = 0;//reset strecthedCol
			}
			return horizontalStretched;

		}else {
			Photograph verticalStretched = new Photograph(photo.getWidth(), 
					2*photo.getHeight());
			
			int stretchedRow = 0;//row for the stretched photo
			
			for(int col = 0; col < photo.getWidth(); col++ ){
				for(int row = 0; row < photo.getHeight(); row++){
					Pixel pix = photo.getPixel(col, row);
					verticalStretched.setPixel(col, stretchedRow, pix);
					verticalStretched.setPixel(col, stretchedRow + 1, pix);
					stretchedRow = stretchedRow + 2;//jump 2 stretched-rows
				}
				stretchedRow = 0;//reset stretchedRow 
			}
			return verticalStretched;
		}
	}
	/**
	 * This method creates a new photo that is twice as wide and twice as long
	 * as the passed photo and then returns this edited photo
	 * @param photo is a picture passed by the user
	 * @return it returns a photo that is twice as wide and twice as long as the
	 * photo passed
	 * 
	 */

	public static Photograph enlargement(Photograph photo) {
		Photograph enlargedPhoto = new Photograph(2*photo.getWidth(),
				2*photo.getHeight());
		int enlargedCol = 0;//column for enlarged photo
		int enlargedRow = 0;//row for enlarged photo
		
		for(int row = 0; row < photo.getHeight(); row++){
			for(int col = 0; col < photo.getWidth(); col++){

				Pixel pix = photo.getPixel(col, row);
				enlargedPhoto.setPixel(enlargedCol, enlargedRow, pix);
				enlargedPhoto.setPixel(enlargedCol, enlargedRow + 1, pix);
				enlargedPhoto.setPixel(enlargedCol+1, enlargedRow, pix);
				enlargedPhoto.setPixel(enlargedCol+1, enlargedRow + 1, pix);
				enlargedCol = enlargedCol + 2;
			}
			enlargedCol = 0;//reset the enlarged-column for each row
			enlargedRow += 2;//jump two enlarged-rows
		}
		return enlargedPhoto;
	}
	/**
	 * This method creates a new photo which has the width of the passed photo's
	 * height and height of the passed photo's width and then rotates the new 
	 * photo 90 degrees clockwise and returns that edited photo
	 * @param photo is a picture passed by the user
	 * @return it returns a picture that is rotated 90 degrees clockwise
	 */

	public static Photograph rotated(Photograph photo) {
		Photograph rotatedPhoto = new Photograph(photo.getHeight(),
				photo.getWidth());
		int rotatedRow = 0;//row for rotated photo
		
		for(int col = 0; col < photo.getWidth(); col++){
			
			int rotatedCol = photo.getHeight()-1;//column for rotated photo
			
			for(int row = 0; row < photo.getHeight(); row++){
				Pixel pix = photo.getPixel(col, row);
				rotatedPhoto.setPixel(rotatedCol, rotatedRow, pix);
				rotatedCol-=1;//decrease rotated column for each new row
			}
			rotatedRow +=1;//increase the rotated row for each new column
		}
		return rotatedPhoto;
	}
	/**
	 * This method creates a new photo that is of the same height and width as
	 * the photo passed and turns the new photo into an upside down version of
	 * the photo passed
	 * @param photo is a picture passed by the user
	 * @return it returns a photo that is upside down of the original photo
	 * 
	 * 
	 */

	public static Photograph upsideDown(Photograph photo) {
		Photograph upsideDownPhoto = new Photograph(photo.getWidth(), 
				photo.getHeight());
		int upsideDownCol = 0;
		int upsideDownRow = 0;
		
		for(int row = photo.getHeight()-1; row >= 0; row--){
			for(int col = photo.getWidth()-1; col >= 0; col--){
				Pixel pix = photo.getPixel(col, row);
				upsideDownPhoto.setPixel(upsideDownCol, upsideDownRow, pix);
				upsideDownCol +=1;
			}
			upsideDownRow +=1;
			upsideDownCol = 0;//reset the upsideDown Column for a new row
		}
		return upsideDownPhoto;
	}
	/**
	 * This method creates a new photo which has the height equal to either the 
	 * width of the photo passed or the height of the photo passed, whichever is
	 * larger. The new photo has all its' pixels set to black. The photo passed
	 * is then copied and the copied photo is turned upside down and another 
	 * copy of the photo is rotated 90 degrees clockwise and both of them are 
	 * put in the new photo side by side in that order.
	 * @param photo is a picture that is passed in by the user
	 * @return it returns a photo that has a weird combination of pictures that
	 * are either rotated 90 degrees clockwise or upside down
	 * 
	 */

	public static Photograph weirdCombo(Photograph photo) {
		int height = photo.getHeight();
		int width = photo.getWidth();
		
		//make the height of the weirdComboPhoto equal to either the height or
		//the width of the original (whichever is larger)
		if(width > height){
			height = width;	
		}
		width = photo.getHeight()+ photo.getWidth();
		Photograph weirdComboPhoto = new Photograph(width, height);
		
		//make the whole weirdComboPhoto black
		for(int row = 0; row < weirdComboPhoto.getHeight(); row++){
			for(int col = 0; col < weirdComboPhoto.getWidth(); col++){
				Pixel pix = new Pixel(0,0,0);
				weirdComboPhoto.setPixel(col, row, pix);
			}
		}
		//make new photos by calling methods
		Photograph upsideDownPhoto = upsideDown(photo);
		Photograph rotatedPhoto = rotated(photo);
		int count = 0;
		
		for(int col = 0; col < upsideDownPhoto.getWidth(); col++){
			for(int row = 0; row < upsideDownPhoto.getHeight(); row++){
				Pixel pix = upsideDownPhoto.getPixel(col,row);
				weirdComboPhoto.setPixel(col, row, pix);
			}
			count = count + 1;//since we want to start the next picture right
			                  //after the last column of the first picture
		}
		
		int rotatedCol = 0;
		
		for(int col = count; col < weirdComboPhoto.getWidth(); col++){
			for(int row = 0; row < rotatedPhoto.getHeight(); row++){
				Pixel pix = rotatedPhoto.getPixel(rotatedCol,row);
				weirdComboPhoto.setPixel(col, row, pix);
			}
			rotatedCol = rotatedCol + 1;
		}
		return weirdComboPhoto;
	}
}

